﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Creation;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit.RevitExtension;
using YJKArch.Utils;

namespace YJKArch.Aproll.FamilyCreate
{
	public class AprollFamilyCreator
	{
		public AprollFamilyCreator(ExternalCommandData cmdData, ElementId materialId, Autodesk.Revit.DB.Document familyDocument)
		{
			this.m_Revit = cmdData;
			this.m_RevitApp = this.m_Revit.Application.Application;
			this.m_FamilyDocument = familyDocument;
			this.m_MaterialId = materialId;
			this.m_FamilyItemFactory = this.m_FamilyDocument.FamilyCreate;
			this.GetDocumentTemplateInfos();
		}

		public Result CreateAproll(double aprollMaxHeight, double aprollMinHeight, double aprollWidth, List<List<EdgeInfo>> aprollPathList, ref string message)
		{
			XYZ origin = new XYZ(0.0, 0.0, 0.0);
			Plane plane = RevitVersionFuncs.CreatePlanByNormalAndOrigin(XYZ.BasisZ, origin);
			SketchPlane pathPlane = RevitVersionFuncs.NewSketchPlane(this.m_FamilyDocument, plane);
			List<Sweep> list = new List<Sweep>();
			foreach (List<EdgeInfo> path in aprollPathList)
			{
				Sweep sweep = null;
				if (!this.CreateSweep(aprollMaxHeight, aprollMinHeight, aprollWidth, path, pathPlane, ref sweep))
				{
					return Autodesk.Revit.UI.Result.Failed;
				}
				if (sweep == null)
				{
					return Autodesk.Revit.UI.Result.Failed;
				}
				list.Add(sweep);
			}
			List<Extrusion> list2 = new List<Extrusion>();
			CombinableElementArray combinableElementArray = new CombinableElementArray();
			foreach (Sweep sweep2 in list)
			{
				combinableElementArray.Append(sweep2);
			}
			foreach (Extrusion extrusion in list2)
			{
				extrusion.get_Parameter(BuiltInParameter.ELEMENT_IS_CUTTING).Set(1);
				combinableElementArray.Append(extrusion);
			}
			Result result;
			try
			{
				this.m_FamilyDocument.CombineElements(combinableElementArray);
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception)
			{
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			return result;
		}

		private bool CreateSweep(double aprollMaxHeight, double aprollMinHeight, double aprollWidth, List<EdgeInfo> path, SketchPlane pathPlane, ref Sweep sweep)
		{
			CurveArrArray curveArrArray = new CurveArrArray();
			CurveArray curveArray = new CurveArray();
			XYZ xyz = new XYZ(0.0, 0.0, 0.0);
			XYZ xyz2 = new XYZ(-aprollWidth, 0.0, 0.0);
			XYZ xyz3 = new XYZ(-aprollWidth, aprollMinHeight, 0.0);
			XYZ xyz4 = new XYZ(0.0, aprollMaxHeight, 0.0);
			curveArray.Append(YJKLineEx.YJKGetBound(xyz, xyz2));
			curveArray.Append(YJKLineEx.YJKGetBound(xyz2, xyz3));
			curveArray.Append(YJKLineEx.YJKGetBound(xyz3, xyz4));
			curveArray.Append(YJKLineEx.YJKGetBound(xyz4, xyz));
			curveArrArray.Append(curveArray);
			CurveLoopsProfile curveLoopsProfile = this.m_Revit.Application.Application.Create.NewCurveLoopsProfile(curveArrArray);
			ProfilePlaneLocation profilePlaneLocation = 0;
			List<Curve> list = new List<Curve>();
			foreach (EdgeInfo edgeInfo in path)
			{
				list.Add(edgeInfo.ConvertTo(this.m_Revit.Application.Application));
			}
			CurveArray curveArray2 = this.CurveListToCurveArray(list);
			bool flag = true;
			try
			{
				sweep = this.m_FamilyDocument.FamilyCreate.NewSweep(flag, curveArray2, pathPlane, curveLoopsProfile, 0, profilePlaneLocation);
			}
			catch (Exception ex)
			{
				string message = ex.Message;
				return false;
			}
			return sweep != null;
		}

		private bool CreateExtrusionForm(List<Curve> section, SketchPlane skplane, double extrusionLength, ref Extrusion extrusion)
		{
			CurveArray curveArray = this.CurveListToCurveArray(section);
			CurveArrArray curveArrArray = new CurveArrArray();
			curveArrArray.Append(curveArray);
			bool flag = true;
			try
			{
				extrusion = this.m_FamilyDocument.FamilyCreate.NewExtrusion(flag, curveArrArray, skplane, extrusionLength);
			}
			catch (Exception ex)
			{
				string message = ex.Message;
				return false;
			}
			return extrusion != null;
		}

		private CurveArray CurveListToCurveArray(List<Curve> curveList)
		{
			CurveArray curveArray = new CurveArray();
			foreach (Curve curve in curveList)
			{
				curveArray.Append(curve);
			}
			return curveArray;
		}

		public Result AddSymbols(ref string symbolName, ref string message)
		{
			try
			{
				FamilyManager familyManager = this.m_FamilyDocument.FamilyManager;
				symbolName = "type1";
				FamilyType currentType = familyManager.NewType(symbolName);
				familyManager.CurrentType = currentType;
			}
			catch (Exception ex)
			{
				message = ex.Message;
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		protected Result GetDocumentTemplateInfos()
		{
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		protected ExternalCommandData m_Revit;

        protected Autodesk.Revit.DB.Document m_FamilyDocument;

		protected ElementId m_MaterialId;

		protected Autodesk.Revit.ApplicationServices.Application m_RevitApp;

		protected FamilyItemFactory m_FamilyItemFactory;
	}
}
